﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LIMS.Entities;
using LIMS.DataAccess;
using System.Collections;
using System.Reflection;
using Castle.Core.Logging;
using NHibernate.Criterion;

namespace LIMS.Service
{
    public class GroupManagementService : IGroupManagementService
    {
        //Private DBA interfaces
        private IDaoFactory oDBFactory;
        private IGroupDAO oGroupDBA;
        private IUserDao oUserDBA;
        private IUserGroupLinkDAO oUGLinkdao;
        private ILogger logger;
        
        //Constructor
        public GroupManagementService(IDaoFactory oDBOp, ILogger oLogger)
        {
            this.oDBFactory = oDBOp;
            this.oGroupDBA = oDBFactory.GetGroupDao();
            this.oUserDBA = oDBFactory.GetUserDao();
            this.oUGLinkdao = oDBFactory.GetUserGroupLinkDAO();
            this.logger = oLogger;
        }
        ///Saves UGL
        /// <summary>
        /// 
        /// </summary>
        /// <param name="oGUL"></param>
        /// <returns></returns>
        public bool SaveUserGroupLink(GroupUserLink oGUL)
        {
            try
            {
                oUGLinkdao.Save(oGUL);
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("Error while getting group user link.", ex);
                return false;
            }
        }

        /// <summary>
        /// Deletes group user link
        /// </summary>
        /// <param name="oGUL"></param>
        /// <returns></returns>
        public bool DeleteUserGroupLink(GroupUserLink oGUL)
        {
            return oUGLinkdao.QuickDelete(oGUL); 
        }
        /// <summary>
        /// Gets list of all users
        /// </summary>
        /// <returns></returns>
        public List<Group> GetAllGroups()
        {
            logger.Info("Getting all groups");
            List<Group> myGroups = new List<Group>();// oGroupDBA.GetAll();


            try
            {
                ICriterion oCriteria = Expression.Eq("Status", Resource.ACTIVE_STATUS);
                myGroups =  oGroupDBA.GetByCriteria(oCriteria);
            }
            catch (Exception ex)
            {
                logger.Error("Error while getting all user group.", ex);
            //    return null;
            }


            List<string> users = new List<string>();
            foreach (Group grp in myGroups)
            {
                foreach (GroupUserLink olink in grp.UserLinks)
                {
                    users.Add(olink.UserId.ToString());
                }
            }

            return myGroups;
        }
              
        /// <summary>
        /// Save
        /// </summary>
        /// <param name="newGroup"></param>
        /// <returns></returns>
        public bool Save(Group newGroup)
        {
            
            return oGroupDBA.QuickSaveOrUpdate(ref newGroup); 
        }

        /// <summary>
        /// Delete
        /// </summary>
        /// <param name="dGroup"></param>
        /// <returns></returns>
        public bool Delete(Group dGroup)
        {
            return oGroupDBA.QuickDelete(dGroup); 
        }

        /// <summary>
        /// Get all users
        /// </summary>
        /// <returns></returns>
        public List<User> GetAllUsers()
        {
            return oUserDBA.GetAll(); 
        }

        /// <summary>
        /// Get group Id by group name
        /// </summary>
        /// <param name="sGroupName"></param>
        /// <returns></returns>
        public int GetGroupIdByGroupName(string sGroupName)
        {
            try
            {
                ICriterion oCriteriaName = Expression.Eq("Name", sGroupName);
                ICriterion oCriteriaStatus = Expression.Eq("Status", Resource.ACTIVE_STATUS);
                ICriterion oCriteria = Expression.And(oCriteriaName, oCriteriaStatus);
                return oGroupDBA.GetUniqueByCriteria(oCriteria).Id;
            }
            catch (Exception ex)
            {
                logger.Error("Error while getting group by group name for Group Name: "+sGroupName, ex);
                return 0;
            }
        }

        /// <summary>
        /// Get name by Id
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public string GetGroupNameByGroupId(int Id)
        {
            return oGroupDBA.GetById(Id).Name;
        
        }

        /// <summary>
        /// Get user group link by user Id
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public List<GroupUserLink> GetAssociatedUserGroupLinksbyUserId(int Id)
        {
            try
            {
                ICriterion oCriteria = Expression.Eq("UserId", Id);
                return oUGLinkdao.GetByCriteria(oCriteria);
            }
            catch (Exception ex)
            {
                logger.Error("Error while getting group by group name for Group ID : "+Id.ToString(), ex);
                return null;
            }
        }
        /// <summary>
        /// Search Group By Name
        /// </summary>
        /// <param name="sGroupName"></param>
        /// <returns></returns>
        public List<Group> SearchGroupByName(string sGroupName)
        {
            try
            {
                ICriterion oCriteriaName = Expression.Like("Name", "%" + sGroupName + "%");
                ICriterion oCriteriaStatus = Expression.Eq("Status", Resource.ACTIVE_STATUS);
                ICriterion oCriteria = Expression.And(oCriteriaName, oCriteriaStatus);
                return oGroupDBA.GetByCriteria(oCriteria);
            }
            catch (Exception ex)
            {
                logger.Error("Error while getting User Details by Searching Group :" + sGroupName, ex);
                return null;
            }
        }

    }
}
